#include "logmessage.hpp"
#include "socket.hpp"
#include "protocol.hpp"
#include <pthread.h>

class HttpServer
{
    Socket _listensock;
    uint16_t _port;

public:
    HttpServer(uint16_t port)
        : _port(port)
    {
        _listensock.Bind(_port);
        _listensock.Listen();
    }

    void Run()
    {
        while (true)
        {
            string client_ip;
            uint16_t client_port;
            int svcsock = _listensock.Accept(&client_ip, &client_port);
            if (svcsock == -1)
                continue;
            LogMessage(DEBUG, "accept connect success! %s:%d", client_ip.c_str(), client_port);
            // 交给子线程处理
            pthread_t tid;
            pthread_create(&tid, nullptr, ThreadRoutine, (void *)svcsock);
        }
    }

    static void *ThreadRoutine(void *args)
    {
        pthread_detach(pthread_self());
        int svcsock = (int)(long)args;
        string buffer;
        char temp[1024];
        while (true)
        {
            int s = recv(svcsock, temp, sizeof(temp), 0);
            if (s > 0)
            {
                buffer.append(temp, s);
                Request req;
                if (!req.Deserialize(buffer))
                {
                    continue;
                }
                req.WriteFile();
                req.DebugPrint();
                Response resp("HTTP/1.1");
                int len = resp.ReadFile(req._path);
                if (len == -1)
                {
                    resp._state_code = 404;
                    req._path = WebRoot;
                    req._path += "/404page.html";
                    req._suffix = "html";
                    len = resp.ReadFile(req._path);
                }
                else
                    resp._state_code = 200;

                resp._header["Content-Length"] = to_string(len == -1 ? 0 : len);
                resp._header["Content-Type"] = resp._content_types[req._suffix];
                // 测试Cookie机制
                 resp._header["Set-Cookie"] = "username=zty";
                 resp._header["Set-Cookie"] = "password=123123"; //哈希表自动去重，存在问题

                // 测试302临时重定向
                //  resp._state_code = 302;
                //  resp._header["Location"] = "https://www.qq.com";
                string resp_str = resp.Serialize();

                send(svcsock, resp_str.c_str(), resp_str.size(), 0);
                break;
            }
            else
            {
                break;
            }
        }
        close(svcsock);
        return nullptr;
    }
};